package com.example.demo.controller;

import com.alibaba.druid.pool.DruidDataSource;
import com.example.demo.config.ActivitiConfig;
import com.example.demo.config.RedisConfig;
import com.example.demo.task.RedisWatchDog;
import com.googlecode.aviator.AviatorEvaluator;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.redisson.RedissonLock;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.client.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/fw")
public class Test {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private DataSource dataSource;

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @RequestMapping("/fw")
    public String fw(){
        RLock lock = redissonClient.getLock("fw");
        System.out.println("lock:"+lock);
        System.out.println("lock type:"+(lock instanceof RedissonLock));
        boolean b = false;
        Timer timer = null;
        try {
            b = lock.tryLock(10,10, TimeUnit.SECONDS);
            if(b){
                System.out.println("线程"+Thread.currentThread().getName()+"已上锁");
                timer = new Timer();
                RedisWatchDog redisWatchDog = new RedisWatchDog(10,TimeUnit.SECONDS);
                timer.schedule(redisWatchDog,3000,10000/3);
                redisTemplate.opsForValue().set("fw3","100");
                System.out.println(redisTemplate.opsForValue().get("fw2"));
                Integer fw2 = Integer.valueOf(redisTemplate.opsForValue().get("fw2").toString());
                if(fw2<=0){
                    System.out.println("商品已售完。。。");
                    return "fw";
                }
                Integer value = fw2-1;
                System.out.println("消费掉一个商品，商品数量是："+value);
                redisTemplate.opsForValue().set("fw2",value.toString());
            }else {
                System.out.println("线程"+Thread.currentThread().getName()+"没上锁");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("线程"+Thread.currentThread().getName()+"释放锁");
            if(b)
                timer.cancel();
                lock.unlock();

        }

        return "fw";
    }

    @RequestMapping("/fw2")
    public String fw2(){
        Long result = (Long) AviatorEvaluator.execute("1+2+3");
        System.out.println(result);

        return "fw";
    }

    @RequestMapping("/dataSourceTest")
    public String dataSourceTest() throws SQLException {
        DruidDataSource dds = (DruidDataSource) dataSource;
        PreparedStatement preparedStatement = dds.getConnection().prepareStatement("select now()");
        ResultSet resultSet = preparedStatement.executeQuery();
       resultSet.next();
        System.out.println(resultSet.getString(1));
        return "fw";
    }
    @RequestMapping("/activitiTest")
    public String activitiTest() throws SQLException {
        long count = repositoryService.createDeploymentQuery().count();
        System.out.println("部署了"+count+"个流程");
        DeploymentBuilder deployment = repositoryService.createDeployment();//创建一个部署对象
        deployment.name("部署的第二个activiti流程图");
        deployment.addClasspathResource(ActivitiConfig.path+"ListenTest.bpmn");
        Deployment deploy = deployment.deploy();
        System.out.println("流程id："+deploy.getId());
        System.out.println("流程name："+deploy.getName());

        List<ProcessDefinition> processDefinitionQuery = repositoryService.createProcessDefinitionQuery().latestVersion().list();
        for(ProcessDefinition processDefinition : processDefinitionQuery){
            System.out.println("ID_"+processDefinition.getId());
            System.out.println("NAME_"+processDefinition.getName());
            System.out.println("KEY_"+processDefinition.getKey());
            System.out.println("VERSION_"+processDefinition.getVersion());
        }
        return "fw";
    }
    @RequestMapping("/startActivitiTest")
    public String startActivitiTest() throws SQLException {
//        String processDefinitionId="HelloWorld:1:4";
//      runtimeService.startProcessInstanceById(processDefinitionId);
        String processDefinitionKey="myProcess";
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);//启动的永远是最新版本的流程
        System.out.println("流程启动成功");
        System.out.println("部署ID:"+processInstance.getDeploymentId());//指act_re_deployment的id
        System.out.println("流程定义ID:"+processInstance.getProcessDefinitionId());//act_re_procdef里面的id
        System.out.println("流程实例ID:"+processInstance.getId());//act_ru_execution这个表里面的id
        return "fw";
    }
    @RequestMapping("/examineActivitiTest")
    public String examineActivitiTest() throws SQLException {
        List<Task> list = taskService.createTaskQuery().list();
        for(int i = 0;i< list.size();i++){
            System.out.println("待处理的任务："+list.get(i).getName());
            System.out.println("开始处理任务.....");
            taskService.complete(list.get(i).getId());
            System.out.println("任务处理完成.....");
        }
        return "fw";
    }

}
